#include <iostream>
#include <string>
#include <signal.h>
#include "../comm/httplib.h"
#include "oj_control.hpp"
#include "oj_model.hpp"
#include "oj_view.hpp"
#include "../comm/log.hpp"
#include "../comm/util.hpp"

#include <mutex>
#include <vector>
#include <cassert>
#include <fstream>

#include <jsoncpp/json/json.h>

#include "../../api/cpp/ml_api/ml_api.h"

using namespace httplib;
using namespace ns_control;
using namespace ns_model;
using namespace ns_view;
using namespace ns_log;
using namespace ns_util;

static Control *ctrptr = nullptr;

bool CheckLogin(const httplib::Request &req)
{
    std::string cookies = req.get_header_value("Cookie");
    size_t pos = cookies.find("user_id=");
    if (pos == std::string::npos)
        return false;

    pos += 8; // "user_id=" 的长度
    size_t end = cookies.find(';', pos);
    std::string user_id = (end != std::string::npos) ? cookies.substr(pos, end - pos) : cookies.substr(pos);
    return !user_id.empty();
}

bool CheckAdmin(const httplib::Request &req)
{
    std::string cookies = req.get_header_value("Cookie");
    size_t pos = cookies.find("admin=");
    if (pos == std::string::npos)
        return false;

    pos += 6; // "admin=" 的长度
    size_t end = cookies.find(';', pos);
    std::string admin = (end != std::string::npos) ? cookies.substr(pos, end - pos) : cookies.substr(pos);
    return !admin.empty();
}

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        std::cerr << "Usage: " << argv[0] << " port" << std::endl;
        return 1;
    }

    int port = std::stoi(argv[1]);
    Server svr;
    Control ctrl;

    ctrptr = &ctrl;

    svr.set_base_dir("./wwwroot");

    // 管理员登录页面
    svr.Get("/admin/login", [&](const Request &req, Response &res)
            {
        std::string html;
        ctrl.AdminLoginPage(&html);
        res.set_content(html, "text/html;charset=utf-8"); });

    // 管理员登录处理
    svr.Post("/admin/login", [&](const Request &req, Response &res)
             { ctrl.AdminLogin(req, res); });

    // 管理员页面
    svr.Get("/admin", [&](const Request &req, Response &res)
            {
                if (!CheckAdmin(req)) {
                    res.set_redirect("/admin/login");
                    return;
                }
                std::string html;
                ctrl.AdminPage(&html);
                res.set_content(html, "text/html;charset=utf-8"); });

    // 添加题目
    svr.Post("/admin/add_question", [&](const Request &req, Response &res)
             {
                if (!CheckAdmin(req)) {
                    res.set_redirect("/admin/login");
                    return;
                }
                ctrl.AddQuestion(req, res); });

    // 更新题目
    svr.Put("/admin/update_question", [&](const Request &req, Response &res)
             {
                if (!CheckAdmin(req)) {
                    res.set_redirect("/admin/login");
                    return;
                }
                ctrl.UpdateQuestion(req, res); });

    // 删除题目
    svr.Delete(R"(/admin/delete_question/(\d+))", [&](const Request &req, Response &res)
             {
                if (!CheckAdmin(req)) {
                    res.set_redirect("/admin/login");
                    return;
                }
                ctrl.DeleteQuestion(req, res); });

    // 登录页面
    svr.Get("/login", [&](const Request &req, Response &res)
            {
        std::string html;
        ctrl.LoginPage(&html);
        res.set_content(html, "text/html;charset=utf-8"); });

    // 登录处理
    svr.Post("/login", [&](const Request &req, Response &res)
             { ctrl.Login(req, res); });

    // 注册页面
    svr.Get("/register", [&](const Request &req, Response &res)
            {
        std::string html;
        ctrl.RegisterPage(&html);
        res.set_content(html, "text/html;charset=utf-8"); });

    // 注册处理
    svr.Post("/register", [&](const Request &req, Response &res)
             { ctrl.Register(req, res); });

    // 退出
    svr.Get("/logout", [&](const Request &req, Response &res)
            { ctrl.Logout(req, res); });

    // 获取全部的题目
    svr.Get("/all_questions", [&](const Request &req, Response &resp)
            {
                std::string html;
                ctrl.AllQuestions(&html);
                 resp.set_content(html, "text/html;charset=utf-8"); });

    // 获得单个题目
    svr.Get(R"(/question/(\d+))", [&](const Request &req, Response &resp)
            {
                if (!CheckLogin(req)) {
                    resp.set_redirect("/login");
                    return;
                }
        std::string number=req.matches[1];
        std::string html;
        ctrl.OneQuestion(number,&html);
        resp.set_content(html,"text/html;charset=utf-8"); });

    // 判题
    svr.Post(R"(/judge/(\d+))", [&](const Request &req, Response &resp)
             {
                if(!CheckLogin(req)) {
                    resp.set_redirect("/login");
                    return;
                }
                 std::string number = req.matches[1];
                 std::string result_json;
                 ctrl.Judge(number, req, &result_json);
                 resp.set_content(result_json, "text/json;charset=utf-8"); });

    // 提交代码
    svr.Post("/submit", [&](const Request &req, Response &resp)
             {
                if(!CheckLogin(req)) {
                    resp.set_redirect("/login");
                    return;
                }
                Json::Reader reader;
                Json::Value in_value;
                reader.parse(req.body, in_value);
                std::string number = in_value["number"].asString();
                std::string result_json;
                ctrl.Judge(number, req, &result_json);
                resp.set_content(result_json, "text/json;charset=utf-8"); });

    svr.Get("/search", [&](const Request &req, Response &res)
            {
                    std::string keyword = req.get_param_value("keyword");
                    std::string html;
                    ctrl.SearchQuestions(keyword, &html);
                    res.set_content(html, "text/html"); });

    svr.Get("/user/submissions", [&](const Request &req, Response &res)
            { ctrl.UserSubmissions(req, res); });

    // 论坛相关路由
    svr.Get(R"(/forum/(\d+))", [&](const Request &req, Response &res)
            {
                std::string question_number = req.matches[1];
                std::string html;
                ctrl.ForumPage(question_number, &html);
                res.set_content(html, "text/html"); });

    svr.Get(R"(/post/(\d+))", [&](const Request &req, Response &res)
            {
                int post_id = std::stoi(req.matches[1]);
                std::string html;
                ctrl.PostDetailPage(post_id, &html);
                res.set_content(html, "text/html"); });

    svr.Post("/post", [&](const Request &req, Response &res)
             { ctrl.AddPost(req, res); });

    svr.Post("/comment", [&](const Request &req, Response &res)
             { ctrl.AddComment(req, res); });

    // 静态文件路由
    svr.set_mount_point("/", "./template_html");

    LOG(INFO) << "服务器启动成功，端口：" << port << std::endl;
    svr.listen("0.0.0.0", port);
    return 0;
}